package com.ant.storage.service.impl;

import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultPage;
import com.ant.storage.common.ResultVo;
import com.ant.storage.dto.*;
import com.ant.storage.excel.DepExcel;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.*;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DingDingUtil;
import com.ant.storage.utils.RandomUtil;
import com.ant.storage.vo.*;
import com.ant.storage.wechat.WeChatUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Date;
/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author melon
 * @since 2022-03-16
 */
@Service
public class PurchaseOrdersServiceImpl extends ServiceImpl<PurchaseOrdersMapper, PurchaseOrders> implements IPurchaseOrdersService {

    @Resource
    public InventoryMapper inventoryMapper;
    @Resource
    public InventoryLogMapper inventoryLogMapper;
    @Resource
    public CarInventoryMapper carInventoryMapper;
    @Resource
    public CarInventoryLogMapper carInventoryLogMapper;
    @Resource
    public ISubscribeService subscribeService;
    @Resource
    public PurchaseOrdersMapper purchaseOrdersMapper;
    @Resource
    private IPurchaseOrdersService ordersService;
    @Resource
    private IRecordOrderService recordOrderService;
    @Autowired
    private IGoodsPoolCommodityService goodsPoolCommodityService;
    @Resource
    private ISupplierPayListService supplierPayListService;
    @Resource
    private ICarSupplierPayService carSupplierPayService;
    @Resource
    IGoodsPoolService goodsPoolService;
    @Autowired
    public ServletContext servletContext;
    @Resource
    IAuditListService auditListService;
    @Resource
    private PurchaserRecordMapper recordMapper;
    @Autowired
    private IPurchaserRecordService recordService;
    @Resource
    private IInvoiceInfoService infoService;
    @Autowired
    public IApprovalMsgService approvalMsgService;
    @Autowired
    private IPurchaserRecordImgService imgService;
    @Autowired
    private IInventoryLogService logService;

    @Autowired
    private IOperationLogService operationLogService;


    @Override
    public ResultVo getPurchaseOrderList(Map<String, Object> params) {
        return ResultVo.success("", this.baseMapper.getPurchaseOrderList(params));
    }

    @Override
    public List<PurchaseOrders> getPurchaseOrderListById(Integer id) {
        return this.baseMapper.selectList(new QueryWrapper<PurchaseOrders>().eq("parent_id", id).orderByDesc("id"));
    }

    @Override
    public ResultVo getPurchaseOrderComplete(PurchaseOrdersVo purchaseOrdersVo) {
        if (purchaseOrdersVo.getId() == null) {
            throw new AntException(ResultCode.PARAM_IS_BLANK);
        } else {
            PurchaseOrders purchaseOrders = new PurchaseOrders();
            BeanUtils.copyProperties(purchaseOrdersVo, purchaseOrders);
            return ResultVo.success("修改成功", this.baseMapper.updateById(purchaseOrders));
        }
    }

    /**
     * 采购单物品入库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo findGoodsAndWarehousing(PurchaseOrdersDto purchaseDto) {
        synchronized (this) {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            List<PurchaseVo> ordersList = purchaseDto.getPurchaseVoList();
            if (ordersList.size() > 0) {
                ordersList.stream().map(item -> {
                    // 入库处理  通过库存id 和物品id来判断库存
                    Inventory selectOne = inventoryMapper.selectOne(new QueryWrapper<Inventory>()
                            .eq("warehouse_id", item.getWarehouseId())
                            .eq("commodity_id", item.getCommodityId()));
                    // 如果物品存在 库存继续入库是 需要重新计算 库存数量和单价
                    //计算采购单的价格
                    BigDecimal total_good_Price = item.getCommodityPrice().multiply(
                            new BigDecimal(item.getCommodityNumber())
                    );
                    if (selectOne != null) {
                        //计算总的数量
                        BigDecimal GoodsAmount =
                                selectOne.getGoodsAmount().add(new BigDecimal(item.getCommodityNumber()));
                        GoodsAmount.setScale(2, BigDecimal.ROUND_HALF_UP);

                        //计算单个物品总价格
                        Inventory inventory = new Inventory();
                        inventory.setGoodsAmount(GoodsAmount);
                        //计算库存的价格
                        inventory.setGoodsPrice(CalculateUnitPrices(selectOne, item));
                        inventory.setId(selectOne.getId());
                        inventoryMapper.updateById(inventory);

                        insertLoginLog(inventory.getId(), item, purchaseDto.getId(), item.getPurchaserId());
                        PurchaseOrders purchaseOrders = new PurchaseOrders();
                        purchaseOrders.setId(item.getId());
                        purchaseOrders.setGoodsStatus(3);
                        purchaseOrders.setChannel(item.getChannel());
                        purchaseOrders.setGoodsTotalPrice(total_good_Price);
                        purchaseOrders.setWarehouseId(item.getWarehouseId());
                        purchaseOrdersMapper.updateById(purchaseOrders);
                        goodsPoolCommodityService.update(new UpdateWrapper<GoodsPoolCommodity>()
                                .set("commodity_number", item.getCommodityNumber())
                                .set("commodity_price", item.getCommodityPrice())
                                .eq("id", item.getGoodsPoolCommodityId()));
                    } else {
                        // 不存在直接入库
                        Inventory inventory = new Inventory();
                        inventory.setWarehouseId(item.getWarehouseId());
                        inventory.setCommodityId(item.getCommodityId());
                        inventory.setGoodsAmount(new BigDecimal(item.getCommodityNumber()).setScale(2,
                                BigDecimal.ROUND_HALF_UP));
                        inventory.setGoodsPrice(item.getCommodityPrice());
                        inventory.setCreatorBy(userInfo.getNameId().toString());
                        inventory.setCreationTime(new Date());
                        inventoryMapper.insert(inventory);

                        PurchaseOrders purchaseOrders = new PurchaseOrders();
                        purchaseOrders.setId(item.getId());
                        purchaseOrders.setGoodsStatus(3);
                        purchaseOrders.setChannel(item.getChannel());
                        purchaseOrders.setGoodsTotalPrice(total_good_Price);
                        purchaseOrders.setWarehouseId(item.getWarehouseId());
                        purchaseOrdersMapper.updateById(purchaseOrders);
                        goodsPoolCommodityService.update(new UpdateWrapper<GoodsPoolCommodity>()
                                .set("commodity_number", item.getCommodityNumber())
                                .set("commodity_price", item.getCommodityPrice())
                                .eq("id", item.getGoodsPoolCommodityId()));
                        insertLoginLog(inventory.getId(), item, purchaseDto.getId(), item.getPurchaserId());
                    }

                    if (item.getChannel() == 41) {
                        if (item.getSupList() == null || item.getSupList().size() == 0) {
                            throw new AntException("请选择供应商!!!");
                        } else {
                            // 判断是否存在
                            List<SupplierPayList> supplierPayListList =
                                    supplierPayListService.list(new QueryWrapper<SupplierPayList>()
                                            .eq("purchase_orders_id", item.getId())
                                            .eq("subscribe_id", item.getSubscribeId()));

                            if (supplierPayListList != null && supplierPayListList.size() > 0) {
                                supplierPayListService.remove(new QueryWrapper<SupplierPayList>()
                                        .eq("purchase_orders_id", item.getId())
                                        .eq("subscribe_id", item.getSubscribeId()));
                            }

                            List<SupplierPayList> list = item.getSupList().stream().map(items -> {
                                SupplierPayList payList = new SupplierPayList();
                                payList.setSupplierId(items.getSupplierId());
                                payList.setSubscribeId(item.getSubscribeId());
                                payList.setPurchaseOrdersId(item.getId());
                                payList.setPurchaserId(item.getPurchaserId());
                                payList.setAmount(items.getAmount());
                                payList.setGoodsPoolCommodityId(item.getGoodsPoolCommodityId());
                                payList.setPrice(item.getCommodityPrice()); // 单价
                                payList.setTotalPrice(new BigDecimal(items.getAmount())
                                        .multiply(item.getCommodityPrice())); // 总计
                                payList.setCreationTime(new Date());
                                payList.setHandleId(userInfo.getNameId());
                                payList.setHandleTime(new Date());
                                return payList;
                            }).collect(Collectors.toList());
                            supplierPayListService.saveBatch(list);
                            return ResultVo.success("完成采购");
                        }
                    }
                    return null;
                }).collect(Collectors.toList());
                // 更新采购状态 已入库
                subscribeService.update(new UpdateWrapper<Subscribe>()
                        .set("status", 4)
                        .set("handlers", purchaseDto.getHandlers())
                        .set("handler_time", new Date())
                        .set("remark", purchaseDto.getRemark())
                        .eq("id", purchaseDto.getId()));
                Subscribe serviceOne = subscribeService.getOne(new QueryWrapper<Subscribe>().eq("id",
                        purchaseDto.getId()));
                if (serviceOne != null) {
                    goodsPoolService.update(new UpdateWrapper<GoodsPool>().set("status", 5)
                            .eq("id", serviceOne.getParentId()));
                }
                return ResultVo.success("入库成功");
            }
            return ResultVo.fail("入库失败");
        }
    }


    /**
     * 单个物品入库
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultVo findGoodsSingleWarehousing(PurchaserDto dto) {
        synchronized (this) {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            Inventory selectOne = inventoryMapper.selectOne(new QueryWrapper<Inventory>()
                    .eq("warehouse_id", dto.getWarehouseId())
                    .eq("commodity_id", dto.getCommodityNewId()));
            PurchaseVo vo = new PurchaseVo();
            vo.setCommodityPrice(dto.getCommodityPrice());
            vo.setCommodityNumber(dto.getCommodityNumber()); // 入库数量
            vo.setChannel(dto.getChannel());
            vo.setId(dto.getId());
            vo.setWarehouseId(dto.getWarehouseId());
            vo.setRemark(dto.getRemark());
            //修改采购单信息
            UpdateWrapper<PurchaseOrders> wrappers = new UpdateWrapper<>();
            wrappers.set("goods_status", dto.getGoodsStatus()); // 0未完成 1保存中 2 已完成 3 入库
            wrappers.set("channel", dto.getChannel());
            wrappers.set("warehouse_id", dto.getWarehouseId());
            wrappers.set("payment_method", dto.getPaymentMethod());
            wrappers.set("goods_total_price",
                    new BigDecimal(dto.getCommodityNumber()).multiply(dto.getCommodityPrice()));
            wrappers.set("remark", dto.getRemark());
            wrappers.eq("id", dto.getId());
            ordersService.update(wrappers);
            //判断selectOne是否为空
            if ( selectOne==null) {
                // 不存在直接入库
                Inventory inventory = new Inventory();
                inventory.setWarehouseId(dto.getWarehouseId());
                inventory.setCommodityId(dto.getCommodityNewId());
                inventory.setGoodsAmount(new BigDecimal(dto.getCommodityNumber()).setScale(2,BigDecimal.ROUND_HALF_UP));
                inventory.setGoodsPrice(dto.getCommodityPrice());
                inventory.setCreatorBy(userInfo.getNameId().toString());
                inventory.setCreationTime(new Date());
                inventoryMapper.insert(inventory);
                insertLoginLog(inventory.getId(), vo, dto.getSubscribeId(), dto.getPurchaserId());
            } else {
                //计算总的数量
                BigDecimal GoodsAmount = selectOne.getGoodsAmount()
                        .add(new BigDecimal(dto.getCommodityNumber()));
                GoodsAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
                Inventory inventory = new Inventory();
                inventory.setGoodsAmount(GoodsAmount);
                //计算库存的价格
                BigDecimal CalculateTotalPrices = CalculateUnitPrices(selectOne, vo);
                inventory.setGoodsPrice(CalculateTotalPrices);
                inventory.setId(selectOne.getId());
                inventoryMapper.updateById(inventory);
                insertLoginLog(selectOne.getId(), vo, dto.getSubscribeId(), dto.getPurchaserId());
            }
            boolean lean = updateCommodity(dto.getId(), dto.getCommodityId(), dto.getCommodityNewId());
            UpdateWrapper<GoodsPoolCommodity> wrapper = new UpdateWrapper<>();
            if (lean) {
                wrapper.set("commodity_id", dto.getCommodityNewId());
                savelog(dto.getGoodsPoolCommodityId(),"goods_pool_commodity",dto.getCommodityNewId().toString(),
                        dto.getCommodityId().toString(),"commodity_id",dto.toString());
                dto.setCommodityId(dto.getCommodityNewId());
            }
            wrapper.set("commodity_number", dto.getCommodityNumber());
            wrapper.set("commodity_price", dto.getCommodityPrice());
            wrapper.set("channel", dto.getChannel());
            wrapper.eq("id", dto.getGoodsPoolCommodityId());
            goodsPoolCommodityService.update(wrapper);
            //判断是否全部完成入库
            allok(dto.getParentId());
            //计算供应商
            if (dto.getChannel()!=null && dto.getChannel() == 41) {
                if (dto.getSupplierId() == null) {
                    throw new AntException("请选择供应商!!!");
                } else {
                    SupplierPayList payList = new SupplierPayList();
                    payList.setSupplierId(dto.getSupplierId());
                    payList.setSubscribeId(dto.getSubscribeId());
                    payList.setPurchaseOrdersId(dto.getId());
                    payList.setPurchaserId(dto.getPurchaserId());
                    payList.setGoodsPoolCommodityId(dto.getGoodsPoolCommodityId());
                    payList.setCommodityId(dto.getCommodityId());
                    payList.setAmount(dto.getCommodityNumber());
                    payList.setPrice(dto.getCommodityPrice()); // 单价
                    payList.setTotalPrice(new BigDecimal(dto.getCommodityNumber()).multiply(dto.getCommodityPrice())); // 总计
                    payList.setCreationTime(new Date());
                    payList.setHandleId(userInfo.getNameId());
                    payList.setHandleTime(new Date());
                    supplierPayListService.save(payList);
                    return ResultVo.success("完成采购");
                }
            }
            return ResultVo.success("完成采购");
        }
    }

    private BigDecimal CalculateUnitPrices(Inventory inventory, PurchaseVo vo) {
        // 计算库存单价
        BigDecimal GoodsAmount = inventory.getGoodsAmount();
        BigDecimal GoodsPrice = inventory.getGoodsPrice();
        BigDecimal unitPrice1 = GoodsAmount.multiply(GoodsPrice).setScale(5, BigDecimal.ROUND_HALF_UP);
        // 计算入库单价
        BigDecimal CommodityAmount = new BigDecimal(vo.getCommodityNumber());
        BigDecimal CommodityPrice = vo.getCommodityPrice();
        BigDecimal unitPrice2 = CommodityAmount.multiply(CommodityPrice).setScale(5, BigDecimal.ROUND_HALF_UP);

        BigDecimal totalPrice = unitPrice1.add(unitPrice2);
        BigDecimal totalAmout = GoodsAmount.add(CommodityAmount);
        BigDecimal unitPrice = totalPrice.divide(totalAmout, 5, BigDecimal.ROUND_HALF_UP);
        return unitPrice;
    }


    /**
     * 添加供应商信息
     *
     * @param inventory
     * @param vo
     * @return
     */
    private BigDecimal addSup(Inventory inventory, PurchaseVo vo) {
        // 计算库存单价
        BigDecimal GoodsAmount = inventory.getGoodsAmount();
        BigDecimal GoodsPrice = inventory.getGoodsPrice();
        BigDecimal unitPrice1 = GoodsAmount.multiply(GoodsPrice).setScale(5, BigDecimal.ROUND_HALF_UP);
        // 计算入库单价
        BigDecimal CommodityAmount = new BigDecimal(vo.getCommodityNumber());
        BigDecimal CommodityPrice = vo.getCommodityPrice();
        BigDecimal unitPrice2 = CommodityAmount.multiply(CommodityPrice).setScale(5, BigDecimal.ROUND_HALF_UP);

        BigDecimal totalPrice = unitPrice1.add(unitPrice2);
        BigDecimal totalAmout = GoodsAmount.add(CommodityAmount);
        BigDecimal unitPrice = totalPrice.divide(totalAmout, 5, BigDecimal.ROUND_HALF_UP);

        return unitPrice;
    }

    /**
     * 判断是所有的已完成
     *
     * @return
     */
    private void allok(Integer id) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        List<PurchaseOrders> list = ordersService.list(new QueryWrapper<PurchaseOrders>().ne("goods_status", 4)
                .eq("parent_id", id));
        List<PurchaseOrders> ordersList = list.stream().filter(item -> item.getGoodsStatus() == 3).collect(Collectors.toList());
        if (list.size() == ordersList.size()) {
            BigDecimal reduce = ordersList.stream().map(PurchaseOrders::getGoodsTotalPrice).reduce(BigDecimal.ZERO,
                    BigDecimal::add);
            subscribeService.update(new UpdateWrapper<Subscribe>()
                    .set("status", 4)
                    .set("price", reduce)
                    .set("handlers", userInfo.getNameId())
                    .set("handler_time", new Date())
                    .eq("id", id));
            Subscribe serviceOne = subscribeService.getOne(new QueryWrapper<Subscribe>().eq("id", id));
            if (serviceOne != null) {
                goodsPoolService.update(new UpdateWrapper<GoodsPool>().set("status", 5)
                        .eq("id", serviceOne.getParentId()));
            }
        }
    }


    private  void savelog(Integer id, String tableName,String oldVal,String newVal,String fieldName,String jsonStr) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        OperationLog log=new OperationLog();
        log.setParentId(id);
        log.setTableName(tableName);
        log.setOldValue(oldVal);
        log.setNewValue(newVal);
        log.setFieldName(fieldName);
        log.setJsonStr(jsonStr);
        log.setCreateBy(userInfo.getNameId().toString());
        log.setCreateTime(new Date());
        operationLogService.save(log);
    }

    //判断是修改了入库的物品
    private boolean updateCommodity(Integer id, Integer cid, Integer newid) {
        if (id == null || cid == null || newid == null) {
            return false;
        }
        if (!Integer.valueOf(cid).equals(Integer.valueOf(newid))) {
            return true;
        }
        return  false;
    }


    /**
     * 计算价格
     *
     * @return 计算单价
     * Calculate unit price
     */
    private BigDecimal CalculateUnitPrice(Integer inventoryId) {

        List<InventoryLog> list = inventoryLogMapper.selectList(new QueryWrapper<InventoryLog>()
                .eq("inventory_id", inventoryId).eq("stock_state", 1));
        int buySum =
                list.stream().map(item -> Integer.valueOf(item.getGoodsAmount())).mapToInt(Integer::intValue).sum();
        double v =
                list.stream().map(a -> new BigDecimal(String.valueOf(a.getGoodsAmount())).multiply(new BigDecimal(String.valueOf(a.getGoodsPrice())))).reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue();
        BigDecimal divide = BigDecimal.valueOf(v).divide(BigDecimal.valueOf(buySum), 3, BigDecimal.ROUND_HALF_DOWN);
        return divide;
    }


    /**
     * 添加入库日志记录
     */
    public void insertLoginLog(Integer inventoryId, PurchaseVo vo, Integer id, Integer PurchaserId) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        InventoryLog log = new InventoryLog();
        log.setWarehouseId(vo.getWarehouseId());
        log.setInventoryId(inventoryId);
        log.setPurchaserId(PurchaserId);
        log.setGoodsAmount(vo.getCommodityNumber()); // 入库实际数量
        log.setGoodsPrice(vo.getCommodityPrice()); // 入库实际数量
        log.setStockState(1); // 入库
        log.setSubscribeId(id); // 采购单id
        log.setPurchaseOrdersId(vo.getId());
        log.setRemark(vo.getRemark());
        log.setChannelId(vo.getChannel());
        log.setCreatorBy(userInfo.getNameId().toString());
        log.setCreationTime(new Date());
        inventoryLogMapper.insert(log);
    }


    @Override
    public ResultPage findPurchaseOrderPage(PurchaseOrdersDto purchaseOrdersDto) {
        try {
            PageHelper.startPage(purchaseOrdersDto.getPageIndex(), purchaseOrdersDto.getPageSize());
            QueryWrapper<PurchaseOrders> wrapper = new QueryWrapper();
            if (purchaseOrdersDto.getOrdersNumber() != null) {
                wrapper.lambda().eq(PurchaseOrders::getOrdersNumber, purchaseOrdersDto.getOrdersNumber());
            }
            if (purchaseOrdersDto.getPurchaserId() != null) {
                wrapper.lambda().eq(PurchaseOrders::getPurchaserId, purchaseOrdersDto.getPurchaserId());
            }
            wrapper.orderByDesc("id");
            List<PurchaseOrders> purchaseOrdersList = this.baseMapper.selectList(wrapper);
            PageInfo<PurchaseOrders> pageInfo = new PageInfo<>(purchaseOrdersList);
            return new ResultPage(pageInfo);
        } catch (Exception e) {
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }

    /**
     * 获取供应商采购明细分页信息
     *
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> findPurchaseSupplierOrderPage(PurchaseOrdersDto dto) {
        Map<String, Object> map = new HashMap<>();
        map.put("data", purchaseOrdersMapper.selectbyId(dto));
        map.put("total", purchaseOrdersMapper.selectTotal());
        List<SupplierCensusVo> maps = purchaseOrdersMapper.selectSupplierPayCensus();
        map.put("census", maps);
        return map;
    }

    @Override
    public List<SupplierVo> findDetailByIdCensus(Integer id) {
        List<SupplierVo> maps = purchaseOrdersMapper.selectCensus(id);
        return maps;
    }

    @Override
    public ResultVo updateImgUrl(ImgUrlDto dto) {
        if (dto.getOrderList().size() > 0) {
            List<PurchaseOrders> ordersList = dto.getOrderList().stream().map(item -> {
                PurchaseOrders orders = new PurchaseOrders();
                orders.setId(item.getId()); // 采购order id
                orders.setImg(dto.getImgId()); //  图片id
                return orders;
            }).collect(Collectors.toList());
            ordersService.updateBatchById(ordersList);
            return ResultVo.success("更新成功");
        } else {
            return ResultVo.fail("请选择物品信息");
        }
    }

    @Override
    public List<DepExcel> exportdep(Integer depId) {
        return null;
    }

    @Override
    public ResultVo findGoodsRejected(PurchaseOrdersDto purchaseDto) {
        return null;
    }


    /**
     * 车辆单个物品入库
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo findCarWarehousing(PurchaserDto dto) {
        synchronized (this) {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            CarInventory selectOne = carInventoryMapper.selectOne(new QueryWrapper<CarInventory>()
                    .eq("warehouse_id", dto.getWarehouseId())
                    .eq("commodity_id", dto.getCommodityId()));
            UpdateWrapper<PurchaseOrders> wrappers = new UpdateWrapper<>();
            wrappers.set("goods_status", dto.getGoodsStatus()); // 0未完成 1保存中 2 已完成 3 入库
            wrappers.set("channel", dto.getChannel());
            wrappers.set("warehouse_id", dto.getWarehouseId());
            wrappers.set("payment_method", dto.getPaymentMethod());
            wrappers.set("goods_total_price",
                    new BigDecimal(dto.getCommodityNumber()).multiply(dto.getCommodityPrice()));
            wrappers.set("remark", dto.getRemark());
            wrappers.eq("id", dto.getId());
            ordersService.update(wrappers);

            UpdateWrapper<GoodsPoolCommodity> wrapper = new UpdateWrapper<>();
            wrapper.set("commodity_number", dto.getCommodityNumber());
            wrapper.set("commodity_price", dto.getCommodityPrice());
            wrapper.set("channel", dto.getChannel());
            wrapper.eq("id", dto.getGoodsPoolCommodityId());
            goodsPoolCommodityService.update(wrapper);

            PurchaseVo vo = new PurchaseVo();
            vo.setCommodityPrice(dto.getCommodityPrice());
            vo.setCommodityNumber(dto.getCommodityNumber()); // 入库数量
            vo.setChannel(dto.getChannel());
            vo.setSupplierId(dto.getSupplierId());
            vo.setId(dto.getId());
            vo.setWarehouseId(dto.getWarehouseId());
            vo.setRemark(dto.getRemark());

            if (selectOne != null) {
                //计算总的数量
                BigDecimal GoodsAmount = selectOne.getGoodsAmount()
                        .add(new BigDecimal(dto.getCommodityNumber()));
                GoodsAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
                CarInventory inventory = new CarInventory();
                inventory.setGoodsAmount(GoodsAmount);
                //计算库存的价格
                BigDecimal CalculateTotalPrices = CalculateUnitPricesCar(selectOne, vo);
                inventory.setGoodsPrice(CalculateTotalPrices);
                inventory.setId(selectOne.getId());
                carInventoryMapper.updateById(inventory);
                insertCarLog(selectOne.getId(), vo, dto.getSubscribeId(), dto.getPurchaserId());
            } else {
                // 不存在直接入库
                CarInventory inventory = new CarInventory();
                inventory.setWarehouseId(dto.getWarehouseId());
                inventory.setCommodityId(dto.getCommodityId());
                inventory.setGoodsAmount(new BigDecimal(dto.getCommodityNumber()).setScale(2,
                        BigDecimal.ROUND_HALF_UP));
                inventory.setGoodsPrice(dto.getCommodityPrice());
                inventory.setCreatorBy(userInfo.getNameId().toString());
                inventory.setCreationTime(new Date());
                carInventoryMapper.insert(inventory);
                insertCarLog(inventory.getId(), vo, dto.getSubscribeId(), dto.getPurchaserId());
            }
            allok(dto.getParentId());
            //计算供应商
            if (dto.getChannel() == 41) {
                if (dto.getSupplierId() == null) {
                    throw new AntException("请选择供应商!!!");
                } else {
                    CarSupplierPay payList = new CarSupplierPay();
                    payList.setSupplierId(dto.getSupplierId());
                    payList.setSubscribeId(dto.getSubscribeId());
                    payList.setPurchaseOrdersId(dto.getId());
                    payList.setPurchaserId(dto.getPurchaserId());
                    payList.setGoodsPoolCommodityId(dto.getGoodsPoolCommodityId());
                    payList.setCommodityId(dto.getCommodityId());
                    payList.setAmount(dto.getCommodityNumber());
                    payList.setPrice(dto.getCommodityPrice()); // 单价
                    payList.setTotalPrice(new BigDecimal(dto.getCommodityNumber())
                            .multiply(dto.getCommodityPrice())); // 总计
                    payList.setCreationTime(new Date());
                    payList.setCreationId(userInfo.getNameId());
                    payList.setHandleId(userInfo.getNameId());
                    payList.setHandleTime(new Date());
                    carSupplierPayService.save(payList);
                    return ResultVo.success("完成采购");
                }
            }
            return ResultVo.success("完成采购");
        }
    }

    private BigDecimal CalculateUnitPricesCar(CarInventory inventory, PurchaseVo vo) {
        // 计算库存单价
        BigDecimal GoodsAmount = inventory.getGoodsAmount();
        BigDecimal GoodsPrice = inventory.getGoodsPrice();
        BigDecimal unitPrice1 = GoodsAmount.multiply(GoodsPrice).setScale(5, BigDecimal.ROUND_HALF_UP);
        // 计算入库单价
        BigDecimal CommodityAmount = new BigDecimal(vo.getCommodityNumber());
        BigDecimal CommodityPrice = vo.getCommodityPrice();
        BigDecimal unitPrice2 = CommodityAmount.multiply(CommodityPrice).setScale(5, BigDecimal.ROUND_HALF_UP);

        BigDecimal totalPrice = unitPrice1.add(unitPrice2);
        BigDecimal totalAmout = GoodsAmount.add(CommodityAmount);
        BigDecimal unitPrice = totalPrice.divide(totalAmout, 5, BigDecimal.ROUND_HALF_UP);
        return unitPrice;
    }

    /**
     * 添加入库日志记录
     */
    public void insertCarLog(Integer inventoryId, PurchaseVo vo, Integer id, Integer PurchaserId) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        CarInventoryLog log = new CarInventoryLog();
        log.setWarehouseId(vo.getWarehouseId());
        //   log.setSupplierId(vo.getSupplierId());
        log.setInventoryId(inventoryId);
        log.setPurchaserId(PurchaserId);
        log.setGoodsAmount(vo.getCommodityNumber()); // 入库实际数量
        log.setGoodsPrice(vo.getCommodityPrice()); // 入库实际数量
        log.setStockState(1); // 入库
        log.setSubscribeId(id); // 采购单id
        log.setPurchaseOrdersId(vo.getId());
        log.setRemark(vo.getRemark());
        log.setChannelId(vo.getChannel());
        log.setCreatorBy(userInfo.getNameId().toString());
        log.setCreationTime(new Date());
        carInventoryLogMapper.insert(log);
    }

    @Override
    public List<SingleVo> findSingle() {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        return this.baseMapper.selectSinglet(userInfo.getNameId());
    }

    @Override
    public List<SingleVo> findPlanSingle() {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        return this.baseMapper.selectPlanSinglet(userInfo.getNameId());
    }


    /**
     * 账单报销
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo saveSingle(SingleDto dto) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        if (dto.getSingleVo().size() > 0) {
            PurchaserRecord purchaserRecord = new PurchaserRecord();
            purchaserRecord.setRecordNumber("RCD" + RandomUtil.getOrderNumbers(recordMapper.selectLastID()));
            purchaserRecord.setCreationTime(new Date());
            purchaserRecord.setCityId(userInfo.getCityId());
            purchaserRecord.setPurchaserId(userInfo.getNameId());
            purchaserRecord.setReimbursementAmount(dto.getReimbursementAmount());
            purchaserRecord.setImgUrlId(dto.getImgUrlId());
            purchaserRecord.setRemarks(dto.getRemarks());
            purchaserRecord.setTypes(dto.getTypeId());
            recordService.save(purchaserRecord);

            List<RecordOrder> recordOrders = dto.getSingleVo().stream().map(item -> {
                RecordOrder orders = new RecordOrder();
                orders.setPurchaserRecordId(purchaserRecord.getId());
                orders.setPurchaseOrdersId(item.getId());
                return orders;
            }).collect(Collectors.toList());
            recordOrderService.saveBatch(recordOrders);
            if (dto.getTypeId() == 1) {
                List<PurchaseOrders> ordersList = dto.getSingleVo().stream().map(item -> {
                    PurchaseOrders orders = new PurchaseOrders();
                    orders.setId(item.getId()); // is_settlement
                    orders.setIsSettlement(1);
                    return orders;
                }).collect(Collectors.toList());
                ordersService.updateBatchById(ordersList);
            }
            if (dto.getTypeId() == 2) {
                List<InventoryLog> logs = dto.getSingleVo().stream().map(item -> {
                    InventoryLog lg = new InventoryLog();
                    lg.setPlannedId(purchaserRecord.getId());
                    lg.setReimburse(1);
                    lg.setId(item.getInventoryLogId());
                    return lg;
                }).collect(Collectors.toList());
                logService.updateBatchById(logs);
            }

            //采购单状态  报销状态
            if (dto.getIsApproved() == 1) {
                // 添加审核
                AuditList auditList = new AuditList();
                auditList.setParentId(purchaserRecord.getId());
                auditList.setProcessType("reimbursement");
                auditList.setCreationTime(new Date());
                // 添加审核记录
                for (String str : dto.getApproval()) {
                    auditList.setNameId(str);
                    auditList.setTypes("1");
                    auditListService.save(auditList);
                }
                for (String str2 : dto.getNotify()) {
                    auditList.setNameId(str2);
                    auditList.setTypes("2");
                    auditListService.save(auditList);
                }
                try {
                    String str = addInvoiceInfo(purchaserRecord.getId(), dto.getSingleVo(), dto.getRemarks(),
                            dto.getImgUrlId(), dto.getAnnexs(), dto.getReimbursementAmount(), dto.getApproval(),
                            dto.getNotify());
                    UpdateWrapper<PurchaserRecord> updateWrapper = new
                            UpdateWrapper<PurchaserRecord>().set(
                            "process_instance_id", str).eq("id", purchaserRecord.getId());
                    recordService.update(updateWrapper);
                    return ResultVo.success("操作成功");
                } catch (AntException e) {
                    throw new AntException("操作失败");
                }
            }
            return ResultVo.success("提交成功");
        } else {
            throw new AntException("请选择需要报销的订单");
        }
    }

    public String addDingDing(SingleDto dto, List<String> str) throws Exception {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            FundsDto fundsDto = new FundsDto();
            fundsDto.setAccess_token(DingDingUtil.obtainToken());
            fundsDto.setOriginator_userid(userInfo.getDingTalk());
            fundsDto.setDeptId(userInfo.getDepId());
            fundsDto.setApprover_userid(dto.getApproval());
            fundsDto.setCc_userId(dto.getNotify());
            fundsDto.setDate(dto.getDate());
            fundsDto.setUrgency("24小时完成");
            fundsDto.setAmount(dto.getReimbursementAmount().toString());
            fundsDto.setPicture(str);
            fundsDto.setReason(dto.getRemarks());
            fundsDto.setCompanyName(userInfo.getDepName());
            if (dto.getSingleVo() != null && dto.getSingleVo().size() > 0) {
                List<ReimbursementProjectDto> collect = dto.getSingleVo().stream().map(m -> {
                    ReimbursementProjectDto dto1 = new ReimbursementProjectDto();
                    dto1.setProjectName(m.getCommodityName());
                    dto1.setAmount(m.getCommodityNumber().toString());
                    dto1.setProjectPrice(m.getCommodityPrice());
                    dto1.setTotalPrice(m.getCommodityNumber().multiply(m.getCommodityPrice()));
                    return dto1;
                }).collect(Collectors.toList());

                fundsDto.setProjectDtoList(collect);
            }
            //System.out.println(fundsDto);
            return DingDingUtil.Reimbursement(fundsDto);
        } catch (Exception e) {
            throw new AntException(ResultCode.FAILURE.getResultCode(), e.getMessage());
        }

    }


    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public String addInvoiceInfo(Integer rid, List<SingleVo> singleVo, String remarks,
                                 String annex, List<String> annexs, BigDecimal amount, List<String> approval,
                                 List<String> notify
    ) throws AntException {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            InvoiceInfo info = new InvoiceInfo();
            info.setWeChat(userInfo.getWeChat());
            info.setUserName(userInfo.getUserName());
            info.setCityId(userInfo.getCityId());
            info.setDepId(userInfo.getDepId());
            info.setInvoiceType(2);
            info.setInvoiceNumber("QK" + RandomUtil.getOrderNumbers(recordMapper.selectLastID()));
            info.setInvoicePrice(amount);
            info.setInvoiceName("采购报销");
            info.setReimbursementType(25);
            info.setReimbursementTypeText("采购报销");
            info.setAnnex(annex);
            info.setAnnexs(annexs);
            info.setApproval(approval);
            info.setNotify(notify);
            info.setIsReimburse(1);
            info.setInvoiceNotes(remarks);
            info.setAccountUrgency("24小时完成");
            info.setCreateBy(userInfo.getNameId().toString());
            info.setCreationTime(new Date());
            info.setAccountName(null);
            info.setAccountBank(null);
            info.setAccountNumber(null);
            info.setHouseLeaseId(rid);
            List<ReimburseDetail> list = new ArrayList<>();
            if (singleVo != null && singleVo.size() > 0) {
                singleVo.forEach(item -> {
                    ReimburseDetail detail = new ReimburseDetail();
                    detail.setProjectName(item.getCommodityName());
                    detail.setProjectAmount(item.getCommodityNumber() == null || item.getCommodityNumber().equals("") ? "1" : item.getCommodityNumber().toString());
                    detail.setProjectUnit(item.getCommodityUnits());
                    detail.setProjectPrice(item.getCommodityPrice());
                    list.add(detail);
                });
            }
            info.setDetailList(list);
            //       System.out.println(info);
            String str = WeChatUtils.launchWeChatData(info);
            info.setProcessInstanceId(str);
            infoService.save(info);
            ApprovalMsg msg = new ApprovalMsg();
            msg.setParentId(info.getId());
            msg.setApprovalType("rent_review");
            msg.setApprovalUser(userInfo.getUserName());
            msg.setApprovalUserId(userInfo.getNameId());
            msg.setSpNo(str);
            msg.setCreationTime(new Date());
            approvalMsgService.save(msg);
            return str;
        } catch (NullPointerException e) {
            throw new AntException(ResultCode.FAILURE.getCode(), e.getMessage());
        }
    }


}
